#include "Sock.hpp"
#define NUM 1024

struct pollfd event_array[NUM];

void Usage(std::string proc)
{
    std::cout << "Usage: " << proc << " port" << std::endl;
}

// ./poll_server port
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(1);
    }

    int listen_sockfd = Sock::Socket();
    // 初始化
    event_array[0].fd = listen_sockfd;
    event_array[0].events |= POLLIN;
    for (int i = 1; i < NUM; ++i)
    {
        event_array[i].fd = -1;
        event_array[i].events = 0;
        event_array[i].revents = 0;
    }

    Sock::Bind(listen_sockfd, static_cast<uint16_t>(atoi(argv[1])));
    Sock::Listen(listen_sockfd);
    // int fd = Sock::Accept(listen_sockfd);
    while (true)
    {
        // 毫秒
        // int timeout = 0;
        int timeout = -1;
        //int timeout = 1000;
        int ret = poll(event_array, NUM, timeout);
        switch (ret)
        {
        case -1:
            fprintf(stderr, "Poll: %s\n", strerror(errno));
            break;
        case 0:
            fprintf(stdout, "time out!\n");
            break;
        default:
            // 有新事件到来
            fprintf(stdout, "有新事件到来！\n");
            // 处理新事件
            for (int i = 0; i < NUM; ++i)
            {
                // 有新的读事件到来
                if (event_array[i].revents & POLLIN)
                {
                    // 新链接到来
                    fprintf(stdout, "有新链接到来！\n");
                    if (event_array[i].fd == listen_sockfd)
                    {
                        int fd = Sock::Accept(listen_sockfd);
                        int pos = 0;
                        // 找到空位置进行插入
                        for (; pos < NUM; ++pos)
                        {
                            if (event_array[pos].fd == -1)
                                break;
                        }
                        // 服务器满载
                        if (pos == NUM)
                        {
                            fprintf(stdout, "服务器满载了！\n");
                            close(fd);
                        }
                        // 找到空位
                        event_array[pos].fd = fd;
                        event_array[pos].events |= POLLIN; // 关心读事件
                        event_array[pos].revents = 0;
                    }
                    else
                    {
                        // 普通读事件
                        char buffer[NUM];
                        ssize_t s = read(event_array[i].fd, buffer, sizeof(buffer) - 1);
                        switch (s)
                        {
                        case -1:
                            fprintf(stderr, "Read: %s\n", strerror(errno));
                            close(event_array[i].fd);
                            event_array[i].fd = -1;
                            event_array[i].events = 0;
                            event_array[i].revents = 0;
                            break;
                        case 0:
                            fprintf(stdout, "对端链接关闭了！\n");
                            close(event_array[i].fd);
                            event_array[i].fd = -1;
                            event_array[i].events = 0;
                            event_array[i].revents = 0;
                            break;
                        default:
                            // 读取成功
                            fprintf(stdout, "读取成功！\n");
                            buffer[s - 1] = '\0';
                            fprintf(stdout, "client[%d]# %s\n", event_array[i].fd, buffer);
                            break;
                        }
                    }
                }
                // 有新的写事件到来
                if (event_array[i].revents & POLLOUT)
                {
                    // TODO
                }
            }
            break;
        }
    }

    // close(fd);
    close(listen_sockfd);
}